﻿using Microsoft.Extensions.Configuration;
using Library.Common.Model;
using Microsoft.Extensions.Hosting;
using Synthesize.Common.Domain.Aggregation.ValueObject;
using Synthesize.Common.ServiceInterface.UseCase;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using Library.Core.Application.BaseAction;
using Library.Core.Application.IInfrastructure;
using Library.Core.Application;
using Synthesize.Common.ServiceInterface.Dtos.Files;

namespace Synthesize.Common.Application.UseCase
{
    /// <summary>
    /// 文件上传逻辑
    /// </summary>
    public class UploadService : BaseService, IUploadService
    {
        private readonly IHostEnvironment _hostEnv;
        private readonly IConfiguration _configuration;
        private readonly List<string> fileSignature = new List<string>()
        {
          "DOC","DOCX","PDF","ZIP","PNG","JPG","JPEG","GIF","BMP","XLS","XLSX","PPT","PPTX","RAR","7Z","TXT"
        };

        public UploadService(IIocContainer container
            , IHostEnvironment hostEnvironment, IConfiguration configuration
            ) : base(container)
        {
            this._hostEnv = hostEnvironment;
            this._configuration = configuration;
        }
        

        /// <summary>
        /// 上传文件
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<BaseApiResult<UploadFileOutput>> Upload(UploadFileInput input)
        {
            return await HandleAsync(async () =>
            {
                var result = new UploadFileOutput();

                var config = GetUploadSettings(input.UploadType);
                string[] fileFormatArray = config.suffix.Split(',');
                var files = input.Files;
                if (!files.Any())
                {
                    throw new ApplicationsException($"请选择上传的文件。");
                }
                var maxlength = config.maxLength;

                foreach (var file in files)
                {
                    if (file.Length > maxlength)
                    {
                        throw new ApplicationsException($"上传文件大小限制为{(int)(maxlength / 1048576)}MB！");
                    }
                    
                    string filePath = $@"{_hostEnv.ContentRootPath}/wwwroot/{input.HomeFolder}/{config.saveSubPath}/"; //将就linux/路径  win支持混编路径
                    var dtNow = $@"{DateTime.Now:yyyy-MM}/";
                    filePath += dtNow;
                    if (!Directory.Exists(filePath))
                    {
                        Directory.CreateDirectory(filePath);
                    }

                    string suffix = Path.GetExtension(ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"'));
                    if (!string.IsNullOrWhiteSpace(suffix))
                    {
                        suffix = suffix.Remove(0, 1);
                    }
                    if (!fileFormatArray.Contains(suffix.ToLower()))
                    {
                        throw new ApplicationsException($"上传文件格式限制为{config.suffix}");
                    }
                    var upperSuffix = suffix.ToUpper();
                    if (!fileSignature.Contains(upperSuffix))//包含后缀的才验证
                    {
                        throw new ApplicationsException($"上传文件类型无效.");
                    }

                    var fileName  = Guid.NewGuid() + "." + suffix;
                    using (FileStream fs = File.Create(filePath + fileName))
                    {
                        await file.CopyToAsync(fs);
                        await fs.FlushAsync();
                    }

                    result.Srcs.Add($"/src/{input.HomeFolder}/{config.saveSubPath}/{dtNow}/{fileName}");
                    result.FileNames.Add(fileName);
                }
                return result;
            });
        }

        private (long maxLength, string suffix, string saveSubPath) GetUploadSettings(UploadTypeEnum uploadTypeEnum)
        {
            var result = new ValueTuple<long, string, string>();
            switch (uploadTypeEnum)
            {
                case UploadTypeEnum.Default:
                    result.Item1 = _configuration.GetValue<long>("UploadSettings:0:maxLength");
                    result.Item2 = _configuration.GetValue<string>("UploadSettings:0:suffix");
                    result.Item3 = _configuration.GetValue<string>("UploadSettings:0:saveSubPath");
                    break;
                case UploadTypeEnum.Image:
                    result.Item1 = _configuration.GetValue<long>("UploadSettings:1:maxLength");
                    result.Item2 = _configuration.GetValue<string>("UploadSettings:1:suffix");
                    result.Item3 = _configuration.GetValue<string>("UploadSettings:1:saveSubPath");
                    break;
                case UploadTypeEnum.Document:
                    result.Item1 = _configuration.GetValue<long>("UploadSettings:2:maxLength");
                    result.Item2 = _configuration.GetValue<string>("UploadSettings:2:suffix");
                    result.Item3 = _configuration.GetValue<string>("UploadSettings:2:saveSubPath");
                    break;
            }
            return result;
        }

    }
}
